package com.three.server.service.imp;

import com.alibaba.fastjson.JSON;
import com.smartcar.common.constants.OrderConstants;
import com.smartcar.common.domain.Order;
import com.smartcar.common.domain.request.DriverRequest;
import com.smartcar.common.domain.request.OrderRequest;
import com.smartcar.common.domain.request.OrderStatePageVo;
import com.smartcar.common.domain.response.OrderMoneyResponse;
import com.smartcar.common.domain.response.OrderPersonResponse;
import com.smartcar.common.domain.response.OrderResponse;
import com.smartcar.common.result.Result;
import com.smartcar.common.utils.StringUtils;
import com.three.common.request.FenceRequest;
import com.three.common.response.SendOrderResponse;
import com.three.server.mapper.OrderMapper;
import com.three.server.scheduled.SyncOrder;
import com.three.server.service.OrderService;
import com.three.server.unit.FenceUtil;
import lombok.extern.log4j.Log4j2;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 1    @ProjectName : driverMe_dev
 *
 * @PackageName : com.three.server.service.impl
 * @ClassName : OrderServiceImpl
 * @Author : ZhouTeng
 * @CreateTime : 2023/10/15 16:48
 */

@Service
@Log4j2
public class OrderServiceImpl implements OrderService {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private SyncOrder syncOrder;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public ArrayList<OrderResponse> orderList() {
        return null;
    }

    @Override
    public OrderPersonResponse personMessage(OrderRequest orderRequest) {
        return null;
    }

    @Override
    public OrderMoneyResponse moneyMessage(OrderRequest orderRequest) {
        return null;
    }


    @Override
    public int insertOrder(OrderRequest orderRequest) {
        FenceRequest build = FenceRequest.builder().longitude(orderRequest.getLongitudeStart()).latitude(orderRequest.getLatitudeStart()).build();
        //根据经纬度查询
        String query = FenceUtil.query(build);
        if(StringUtils.isEmpty(query)){
            return -1001;
        }
        int i = orderMapper.insertOrder(orderRequest);
        //TODO 订单存入围栏中
       redisTemplate.opsForHash().put(OrderConstants.ORDERS+"_"+query,orderRequest.getOrderNumber(), JSON.toJSONString(orderRequest));
       return i;
    }

    @Override
    public int updateOrderByDriver(OrderRequest orderRequest) {
        return orderMapper.updateOrderByDriver(orderRequest);
    }

    @Override
    public List<Order> queryOrderByOrderState(OrderStatePageVo orderStatePageVo) {
//        ArrayList<Order> orders = orderMapper.queryOrderByOrderState(orderStatePageVo.getOrderState());
        return null;
    }

    @Override
    public List<OrderRequest> selectOrder(OrderRequest orderRequest) {
       return orderMapper.selectOrder(orderRequest);
    }

    @Override
    public List<OrderRequest> orderFindByPhone(String personPhone) {
      return orderMapper.orderFindByPhone(personPhone);
    }

    @Override
    public List<OrderRequest> selectPcOrder() {
        return orderMapper.selectPcOrder();
    }

    @Override
    public int updatePc(OrderRequest orderRequest) {
        return orderMapper.updatePc(orderRequest);
    }

    @Override
    public OrderRequest echoOrder(Long id) {
        return orderMapper.echoOrder(id);
    }

//    @Override
//    public void downLoad(HttpServletResponse response) {
//        ArrayList<Order> orders = orderMapper.queryOrderByOrderState(0);
//        ExcelUtil<Order> orderExcelUtil = new ExcelUtil<>(Order.class);
//        orderExcelUtil.exportExcel(response, orders, "订单");
//    }

    @Override
    public SendOrderResponse sendOrder(FenceRequest fenceRequest) {
        String query = FenceUtil.query(fenceRequest);
        ArrayList<OrderResponse> list = new ArrayList<>();
        Set<Object>   keys = redisTemplate.opsForHash().keys(OrderConstants.ORDERS + "_" + query);
        if(0 != keys.size()){
            new ArrayList<>(keys).stream().forEach(object -> {
                //TODO 获取订单
                String o = (String)redisTemplate.opsForHash().get(OrderConstants.ORDERS + "_" + query, String.valueOf(object));
                OrderResponse orderResponse = JSON.parseObject(o, OrderResponse.class);
                list.add(orderResponse);
            });
        }
        return  SendOrderResponse.builder().list(list).total(list.size()).build();
    }

    @Override
    public Object driverGetOrder(DriverRequest driverRequest) {
        FenceRequest build = FenceRequest.builder().longitude(driverRequest.getLongitude()).latitude(driverRequest.getLatitude()).build();
        String query = FenceUtil.query(build);
        RLock lock = redissonClient.getLock(OrderConstants.LOCK+driverRequest.getOrderNumber());
        try {
            boolean tage = lock.tryLock(10, TimeUnit.SECONDS);
            if(tage){
                try {
                    //上锁5
                    lock.lock(OrderConstants.LOCK_TIME, TimeUnit.SECONDS);
                    //修改数据库状态
                    //TODO 司机的个人信息
                    OrderRequest order = OrderRequest.builder().orderNumber(driverRequest.getOrderNumber()).orderCity("该订单已被接单").orderState(1).build();
                    int i = orderMapper.updateOrderByDriver(order);
                    //删除掉订单缓存区中的订单
                    Long delete = redisTemplate.opsForHash().delete(OrderConstants.ORDERS + "_" + query, driverRequest.getOrderNumber());
                    if(delete>0){
                        return "抢单成功！";
                    }

                }finally {
                    lock.forceUnlock();
                }
            }else{
                return OrderConstants.STATE_LOCK;
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "订单已被抢走";
    }

}
